package com.scs.application.modules.sys.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.scs.application.consts.GlobalConsts;
import com.scs.application.core.mvc.controller.CrudController;
import com.scs.application.core.utils.DateUtils;
import com.scs.application.core.utils.StringUtils;
import com.scs.application.core.utils.UserUtils;
import com.scs.application.modules.dept.entity.Apply;
import com.scs.application.modules.dept.entity.OprtUse;
import com.scs.application.modules.dept.entity.Use;
import com.scs.application.modules.dept.service.ApplyService;
import com.scs.application.modules.dept.service.OprtUseService;
import com.scs.application.modules.dept.service.UseService;
import com.scs.application.modules.msg.entity.InnerNotice;
import com.scs.application.modules.purchase.entity.Order;
import com.scs.application.modules.purchase.service.OrderService;
import com.scs.application.modules.report.handler.BeforeReport;
import com.scs.application.modules.sys.dto.CountInfoDTO;
import com.scs.application.modules.sys.dto.TaskTodoDTO;
import com.scs.application.modules.sys.entity.Menu;
import com.scs.application.modules.sys.entity.User;
import com.scs.application.modules.sys.entity.Workbench;
import com.scs.application.modules.sys.model.RestResult;
import com.scs.application.modules.sys.service.MenuService;
import com.scs.application.modules.sys.service.OfficeService;
import com.scs.application.modules.sys.service.UserService;
import com.scs.application.modules.sys.service.WorkbenchService;
import com.scs.application.modules.wm.entity.Transfer;
import com.scs.application.modules.wm.entity.WorkOrder;
import com.scs.application.modules.wm.enums.WorkOrderType;
import com.scs.application.modules.wm.service.TransferService;
import com.scs.application.modules.wm.service.WorkOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 工作台 前端控制器
 * </p>
 */
@RestController
@RequestMapping("/sys/workbench")
public class WorkbenchController extends CrudController<WorkbenchService, Workbench>{
    @Autowired
    OfficeService officeService;
    @Autowired
    ApplyService applyService;
    @Autowired
    OprtUseService oprtUseService;
    @Autowired
    UseService useService;
    @Autowired
    OrderService orderService;
    @Autowired
    WorkOrderService workOrderService;
    @Autowired
    UserService userService;
    @Autowired
    TransferService transferService;
    @Autowired
    MenuService menuService;

    /***
     * @param entityList
     * @Author: Tai
     * @date: 2024/6/14
     * @Description:  批量保存菜单
     */
    @PostMapping("/saveBatchMenu")
    public RestResult saveBatchMenu(@Valid @RequestBody List<Workbench> entityList) {
        boolean isOk = service.saveBatchMenu(entityList);
        if (!isOk) {
            return RestResult.error("数据保存失败");
        }
        return RestResult.ok("数据保存成功", entityList);
    }


    /***
     * @Author: Tai
     * @date: 2024/6/14
     * @Description:  根据用户标志查询
     */
    @GetMapping("/getByUserCode")
    public RestResult getByUserCode() {
        return RestResult.ok("查询成功", service.list(Wrappers.<Workbench>query().eq("user_code", UserUtils.currentUser().getCode()).orderByAsc("sort_num")));
    }

    @GetMapping("/listNews")
    public RestResult<List> listNews() {
        List<InnerNotice> result = service.listNews();
        return RestResult.ok("查询成功", result);
    }


    /***
     * @param
     * @return: com.scs.application.modules.sys.model.RestResult
     * @Author: Tai
     * @date: 2024/6/13
     * @Description:  获取工作台数据
     */
    @GetMapping("/loadInfo")
    public RestResult loadInfo(String getKey) {
        switch (getKey) {
            // 统计数据
            case "getCountInfoList" : {
                return RestResult.ok("查询成功", getCountInfo());
            }
            // 统计数据
            case "getTaskTodo" : {
                return RestResult.ok("查询成功", getTaskTodo());
            }
        }
        return RestResult.ok("查询成功");
    }

    /***
     * @param data
     * @return: void
     * @Author: Tai
     * @date: 2024/6/13
     * @Description:  获取统计数据
     */
    private Object getCountInfo() {
        Map<String,CountInfoDTO> data = new HashMap<>();
        CountInfoDTO countInfo;

        Map<String,Object> dataOne = null;
        String deptId = UserUtils.currentUser().getDeptId();
        boolean isAll = BeforeReport.getFlagAllData();

        List<String> menuRouteNameList = menuService.getUserMenu()
                .stream().map(Menu::getName).distinct().collect(Collectors.toList());
        String extra = isAll ? "所有科室" : "当前科室";

        String dateBegin = DateUtils.format(DateUtils.getFirstDayOfMonth(DateUtils.now()), "yyyy-MM-dd") + " 00:00:00";
        String dateEnd = DateUtils.format(DateUtils.getLastDayOfMonth(DateUtils.now()), "yyyy-MM-dd") + " 23:59:59";

        //本月申领数     deptApplyCount
        countInfo = new CountInfoDTO();
        countInfo.setExtra(extra)
                .setValue(
                        applyService.count(Wrappers.<Apply>query()
                                .eq(!isAll,"ifnull(dept_id,'')", deptId)
                                .eq("flow_status", GlobalConsts.FLOW_END_VALUE)
                                .between("flow_modified",dateBegin,dateEnd)
                        )
                )
        ;
        data.put("deptApplyCount", countInfo);

        //本月消耗金额     deptCostAmount
        countInfo = new CountInfoDTO();
        QueryWrapper queryWrapperOprtUse = Wrappers.<OprtUse>query().select("sum(amount) as amount")
                .eq("flow_status", GlobalConsts.FLOW_END_VALUE)
                .between("flow_modified",dateBegin,dateBegin);
        if (!isAll) {
            queryWrapperOprtUse.and(wrapper -> Wrappers.<OprtUse>query().eq("ifnull(dept_id,'')", deptId).or().eq("ifnull(exec_dept_id,'') ", deptId));
        }
        OprtUse oprtUseSum = oprtUseService.getOne(queryWrapperOprtUse,false);
        Use useSum = useService.getOne(Wrappers.<Use>query()
                        .select("sum(amount) as amount")
                        .eq(!isAll,"ifnull(dept_id,'')", deptId)
                        .eq("flow_status", GlobalConsts.FLOW_END_VALUE)
                        .between("flow_modified",dateBegin,dateEnd)
                ,false);
        double sumAll = 0;
        if (oprtUseSum != null && oprtUseSum.getAmount() != null) {
            sumAll += oprtUseSum.getAmount();
        }
        if (useSum != null && useSum.getAmount() != null) {
            sumAll += useSum.getAmount();
        }
        countInfo.setExtra(extra)
                .setValue(sumAll)
        ;
        data.put("deptCostAmount", countInfo);


        //本月订单数     orderCount
        countInfo = new CountInfoDTO();
        // 没有菜单权限，则隐藏该统计
        if (!menuRouteNameList.contains(getMenuRouteName("order"))) {
            countInfo.setExtra(extra).setShow(0);
        }else {
            countInfo.setExtra(extra)
                    .setValue(
                            orderService.count(Wrappers.<Order>query()
                                    .eq(!isAll,"ifnull(dept_id,'')", deptId)
                                    .eq(!isAll,"ifnull(dept_id_demand,'')", deptId)
                                    .eq("flow_status", GlobalConsts.FLOW_END_VALUE)
                                    .between("flow_modified",dateBegin,dateEnd)
                            )
                    )
            ;
        }
        data.put("orderCount", countInfo);

        //本月入库数     workInCount
        countInfo = new CountInfoDTO();
        if (!menuRouteNameList.contains(getMenuRouteName(WorkOrderType.IN_MANUAL))
        && !menuRouteNameList.contains(getMenuRouteName(WorkOrderType.IN_ASN))
        && !menuRouteNameList.contains(getMenuRouteName(WorkOrderType.IN_INIT))
        && !menuRouteNameList.contains(getMenuRouteName(WorkOrderType.IN_PACKAGE))
        ) {
            countInfo.setExtra(extra).setShow(0);
        }else {
            countInfo.setExtra(extra)
                    .setValue(
                            workOrderService.count(Wrappers.<WorkOrder>query()
                                    .eq("flow_status", GlobalConsts.FLOW_END_VALUE)
                                    .in("bus_type", WorkOrderType.WorkOrderTypeIn)
                                    .between("flow_modified",dateBegin,dateEnd)
                            )
                    )
            ;
        }

        data.put("workInCount", countInfo);

        //供应商退货     spOutCount
        countInfo = new CountInfoDTO();
        // 没有菜单权限，则隐藏该统计
        if (!menuRouteNameList.contains(getMenuRouteName(WorkOrderType.OUT_SP))) {
            countInfo.setExtra(extra).setShow(0);
        }else {
            countInfo.setExtra(extra)
                    .setValue(
                            workOrderService.count(Wrappers.<WorkOrder>query()
                                    .eq("flow_status", GlobalConsts.FLOW_END_VALUE)
                                    .in("bus_type", WorkOrderType.OUT_SP)
                                    .between("flow_modified",dateBegin,dateEnd)
                            )
                    )
            ;
        }

        data.put("spOutCount", countInfo);

        //科室退货     deptReturnCount
        countInfo = new CountInfoDTO();
        // 没有菜单权限，则隐藏该统计
        if (!menuRouteNameList.contains(getMenuRouteName(WorkOrderType.IN_DEPT_RETURN))) {
            countInfo.setExtra(extra).setShow(0);
        }else {
            countInfo.setExtra(extra)
                    .setValue(
                            transferService.count(Wrappers.<Transfer>query()
                                    .eq("flow_status", GlobalConsts.FLOW_END_VALUE)
                                    .in("type", WorkOrderType.IN_DEPT_RETURN)
                                    .between("flow_modified",dateBegin,dateEnd)
                            )
                    )
            ;
        }
        data.put("deptReturnCount", countInfo);

        //本月调拨出库     workOutShiftCount
        countInfo = new CountInfoDTO();

        // 没有菜单权限，则隐藏该统计
        if (!menuRouteNameList.contains(getMenuRouteName(WorkOrderType.OUT_SHIFT))) {
            countInfo.setExtra(extra).setShow(0);
        }else {
            countInfo.setExtra(extra)
                    .setValue(
                            transferService.count(Wrappers.<Transfer>query()
                                    .eq("flow_status", GlobalConsts.FLOW_END_VALUE)
                                    .in("type", WorkOrderType.OUT_SHIFT)
                                    .between("flow_modified",dateBegin,dateEnd)
                            )
                    )
            ;
        }

        data.put("workOutShiftCount", countInfo);
        return data;
    }

    /***
     * @return: void
     * @Author: Tai
     * @date: 2024/6/13
     * @Description:  获取待办任务
     */
    private List<TaskTodoDTO> getTaskTodo() {
        List<TaskTodoDTO> todoList = new ArrayList<>();
        TaskTodoDTO todo;
        String deptId = UserUtils.currentUser().getDeptId();
        boolean isAll = BeforeReport.getFlagAllData();
        List<String> menuRouteNameList = menuService.getUserMenu()
                .stream().map(Menu::getName).distinct().collect(Collectors.toList());

        // 科室请领
        // 有菜单权限才进行查询
        if (menuRouteNameList.contains(getMenuRouteName("apply"))) {
            List<Apply> applyList = applyService.list(Wrappers.<Apply>query()
                    .eq(!isAll,"ifnull(dept_id,'')", deptId)
                    .ne("flow_status", GlobalConsts.FLOW_END_VALUE)
                    .ne("flow_status", GlobalConsts.FLOW_CLOSE_VALUE)
            );
            if (!applyList.isEmpty()) {
                for (Apply item : applyList) {
                    todo = new TaskTodoDTO();
                    todo.setBusKey(item.getBusKey()).setBusId(item.getId())
                            .setBusTypeName("科室申领维护").setBusType("apply")
                            .setMenuRouteName(getMenuRouteName("apply")).setRemark(item.getRemark())
                            .setGmtModified(item.getGmtModified()).setModifier(item.getModifier())
                            .setFlowModified(item.getFlowModified()).setFlowModifierName(item.getFlowModifier()).setFlowStatus(item.getFlowStatus());
                    todoList.add(todo);
                }
            }
        }


        // 采购订单
        // 有菜单权限才进行查询
        if (menuRouteNameList.contains(getMenuRouteName("order"))) {
            List<Order> orderList = orderService.list(Wrappers.<Order>query()
                    .eq(!isAll,"ifnull(dept_id,'')", deptId)
                    .ne("flow_status", GlobalConsts.FLOW_END_VALUE)
                    .ne("flow_status", GlobalConsts.FLOW_CLOSE_VALUE)
            );
            if (!orderList.isEmpty()) {
                for (Order item : orderList) {
                    todo = new TaskTodoDTO();
                    todo.setBusKey(item.getBusKey()).setBusId(item.getId())
                            .setBusTypeName("供应商采购").setBusType("order")
                            .setMenuRouteName(getMenuRouteName("order")).setRemark(item.getRemark())
                            .setGmtModified(item.getGmtModified()).setModifier(item.getModifier())
                            .setFlowModified(item.getFlowModified()).setFlowModifierName(item.getFlowModifier()).setFlowStatus(item.getFlowStatus());
                    todoList.add(todo);
                }
            }
        }


        // 入库单
        // 有菜单权限才进行查询
        if (
                menuRouteNameList.contains(getMenuRouteName(WorkOrderType.IN_MANUAL))
                || menuRouteNameList.contains(getMenuRouteName(WorkOrderType.IN_ASN))
                || menuRouteNameList.contains(getMenuRouteName(WorkOrderType.IN_INIT))
                || menuRouteNameList.contains(getMenuRouteName(WorkOrderType.IN_PACKAGE))
        ) {
            List<WorkOrder> workOrderList = workOrderService.list(Wrappers.<WorkOrder>query()
                    .ne("flow_status", GlobalConsts.FLOW_END_VALUE)
                    .ne("flow_status", GlobalConsts.FLOW_CLOSE_VALUE)
                    .in("bus_type", WorkOrderType.WorkOrderTypeIn)
            );

            if (!workOrderList.isEmpty()) {
                for (WorkOrder item : workOrderList) {
                    todo = new TaskTodoDTO();
                    todo.setBusKey(item.getBusKey()).setBusId(item.getId())
                            .setBusTypeName("供应商入库").setBusType(item.getBusType())
                            .setMenuRouteName(getMenuRouteName(item.getBusType())).setRemark(item.getRemark())
                            .setGmtModified(item.getGmtModified()).setModifier(item.getModifier())
                            .setFlowModified(item.getFlowModified()).setFlowModifierName(item.getFlowModifier()).setFlowStatus(item.getFlowStatus());
                    todoList.add(todo);
                }
            }
        }


        // 科室消耗
        // 有菜单权限才进行查询
        if (menuRouteNameList.contains(getMenuRouteName("use"))) {
            List<Use> useList = useService.list(Wrappers.<Use>query()
                    .eq(!isAll,"ifnull(dept_id,'')", deptId)
                    .ne("flow_status", GlobalConsts.FLOW_END_VALUE)
                    .ne("flow_status", GlobalConsts.FLOW_CLOSE_VALUE)
            );

            if (!useList.isEmpty()) {
                for (Use item : useList) {
                    todo = new TaskTodoDTO();
                    todo.setBusKey(item.getUseKey()).setBusId(item.getId())
                            .setBusTypeName("科室消耗维护").setBusType("use")
                            .setMenuRouteName(getMenuRouteName("use")).setRemark(item.getRemark())
                            .setGmtModified(item.getGmtModified()).setModifier(item.getModifier())
                            .setFlowModified(item.getFlowModified()).setFlowModifierName(item.getFlowModifier()).setFlowStatus(item.getFlowStatus());
                    todoList.add(todo);
                }
            }
        }


        // 病人消耗
        // 有菜单权限才进行查询
        if (menuRouteNameList.contains(getMenuRouteName("oprtUse"))) {
            QueryWrapper queryWrapperOprtUse = Wrappers.<OprtUse>query()
                    .ne("flow_status", GlobalConsts.FLOW_END_VALUE)
                    .ne("flow_status", GlobalConsts.FLOW_CLOSE_VALUE);
            if (!isAll) {
                queryWrapperOprtUse.and(wrapper -> Wrappers.<OprtUse>query().eq("dept_id", deptId).or().eq("exec_dept_id", deptId));
            }

            List<OprtUse> oprtUseList = oprtUseService.list(queryWrapperOprtUse);

            if (!oprtUseList.isEmpty()) {
                for (OprtUse item : oprtUseList) {
                    todo = new TaskTodoDTO();
                    todo.setBusKey(item.getBusKey()).setBusId(item.getId())
                            .setBusTypeName("科室消耗计费").setBusType("oprtUse")
                            .setMenuRouteName(getMenuRouteName("oprtUse")).setRemark(item.getRemark())
                            .setGmtModified(item.getGmtModified()).setModifier(item.getModifier())
                            .setFlowModified(item.getFlowModified()).setFlowModifierName(item.getFlowModifier()).setFlowStatus(item.getFlowStatus());
                    todoList.add(todo);
                }
            }
        }


        // 供应商退货
        // 有菜单权限才进行查询
        if (menuRouteNameList.contains(getMenuRouteName(WorkOrderType.OUT_SP))) {
            List<WorkOrder> spOutList = workOrderService.list(Wrappers.<WorkOrder>query()
                    .ne("flow_status", GlobalConsts.FLOW_END_VALUE)
                    .ne("flow_status", GlobalConsts.FLOW_CLOSE_VALUE)
                    .eq(!isAll,"ifnull(dept_id,'')", deptId)
            );

            if (!spOutList.isEmpty()) {
                for (WorkOrder item : spOutList) {
                    todo = new TaskTodoDTO();
                    todo.setBusKey(item.getBusKey()).setBusId(item.getId())
                            .setBusTypeName("供应商退货").setBusType(item.getBusType())
                            .setMenuRouteName(getMenuRouteName(item.getBusType())).setRemark(item.getRemark())
                            .setGmtModified(item.getGmtModified()).setModifier(item.getModifier())
                            .setFlowModified(item.getFlowModified()).setFlowModifierName(item.getFlowModifier()).setFlowStatus(item.getFlowStatus());
                    todoList.add(todo);
                }
            }
        }


        // 科室退货
        // 有菜单权限才进行查询
        if (menuRouteNameList.contains(getMenuRouteName(WorkOrderType.IN_DEPT_RETURN))) {
            List<Transfer> deptReturnList = transferService.list(Wrappers.<Transfer>query()
                    .ne("flow_status", GlobalConsts.FLOW_END_VALUE)
                    .ne("flow_status", GlobalConsts.FLOW_CLOSE_VALUE)
                    .eq("type", WorkOrderType.IN_DEPT_RETURN)
                    .eq(!isAll,"ifnull(dept_id_from,'')", deptId)
            );

            if (!deptReturnList.isEmpty()) {
                for (Transfer item : deptReturnList) {
                    todo = new TaskTodoDTO();
                    todo.setBusKey(item.getBusKey()).setBusId(item.getId())
                            .setBusTypeName("科室退货").setBusType("deptReturn")
                            .setMenuRouteName(getMenuRouteName("deptReturn")).setRemark(item.getRemark())
                            .setGmtModified(item.getGmtModified()).setModifier(item.getModifier())
                            .setFlowModified(item.getFlowModified()).setFlowModifierName(item.getFlowModifier()).setFlowStatus(item.getFlowStatus());
                    todoList.add(todo);
                }
            }
        }


        // 调拨出库
        // 有菜单权限才进行查询
        if (menuRouteNameList.contains(getMenuRouteName(WorkOrderType.OUT_SHIFT))) {
            List<Transfer> deptReturnList = transferService.list(Wrappers.<Transfer>query()
                    .ne("flow_status", GlobalConsts.FLOW_END_VALUE)
                    .ne("flow_status", GlobalConsts.FLOW_CLOSE_VALUE)
                    .eq("type", WorkOrderType.OUT_SHIFT)
            );

            if (!deptReturnList.isEmpty()) {
                for (Transfer item : deptReturnList) {
                    todo = new TaskTodoDTO();
                    todo.setBusKey(item.getBusKey()).setBusId(item.getId())
                            .setBusTypeName("调拨出库").setBusType(WorkOrderType.OUT_SHIFT)
                            .setMenuRouteName(getMenuRouteName(WorkOrderType.OUT_SHIFT)).setRemark(item.getRemark())
                            .setGmtModified(item.getGmtModified()).setModifier(item.getModifier())
                            .setFlowModified(item.getFlowModified()).setFlowModifierName(item.getFlowModifier()).setFlowStatus(item.getFlowStatus());
                    todoList.add(todo);
                }
            }
        }


        if (!todoList.isEmpty()) {
            //填充修改时间
            todoList.stream().filter(tmp -> tmp.getFlowModified() == null && tmp.getGmtModified() != null)
                    .forEach(item -> {
                        item.setFlowModified(item.getGmtModified());
                    });
            //填充修改人
            Map<String,User> userByCode = userService.list(Wrappers.<User>query().in("code",todoList.stream().filter(tmp -> StringUtils.isNotBlank(tmp.getModifier())).map(TaskTodoDTO::getModifier).distinct().collect(Collectors.toList())))
                    .stream().collect(Collectors.toMap(User::getCode,item -> item));
            todoList.stream().filter(tmp -> StringUtils.isBlank(tmp.getFlowModifierName()) && StringUtils.isNotBlank(tmp.getModifier()) && userByCode.containsKey(tmp.getModifier()))
                    .forEach(item -> {
                        item.setFlowModifierName(userByCode.get(item.getModifier()).getName());
            });


            //填充修改时间
            todoList.stream()
                    .forEach(item -> {
                        if (StringUtils.isBlank(item.getFlowStatus())) {
                            item.setFlowStatusName("未知");
                        } else if (item.getFlowStatus().equals(GlobalConsts.FLOW_START_VALUE)) {
                            item.setFlowStatusName("制单");
                        } else {
                            item.setFlowStatusName("待审核");
                        }
                    });
        }


         return  todoList;
    }

    /***
     * @return: void
     * @Author: Tai
     * @date: 2024/6/13
     * @Description:  获取待办任务
     */
    private String getMenuRouteName(String  busType) {
        switch (busType) {
            case WorkOrderType.IN_ASN:
            case WorkOrderType.IN_PACKAGE: {
                return "inorderSP";
            }
            case WorkOrderType.IN_MANUAL:{
                return "inorderManual";
            }
            case WorkOrderType.IN_DEPT_RETURN:
            case "deptReturn": {
                return "deptreturn";
            }
            case WorkOrderType.IN_INIT:{
                return "inorderInit";
            }
            case WorkOrderType.OUT_SHIFT:{
                return "transfer";
            }
            case WorkOrderType.OUT_SP:{
                return "spreturn";
            }
            case "apply":{
                return "apply";
            }
            case "order":{
                return "order";
            }
            case "use":{
                return "deptuse";
            }
            case "oprtUse":{
                return "oprtuse";
            }
        }

         return  null;
    }

}
